﻿<!DOCTYPE html>
<html lang="en">

    <head>
        <title>Auto Session Establishment using DataChannel.js</title>
        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
        <meta charset="utf-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
        <link rel="author" type="text/html" href="https://plus.google.com/+MuazKhan">
        <meta name="author" content="Muaz Khan">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <link rel="stylesheet" href="https://cdn.webrtc-experiment.com/style.css">
        <script>
            var hash = window.location.hash.replace('#', '');
            if (!hash.length) {
                location.href = location.href + '#' + ((Math.random() * new Date().getTime()).toString(36).toUpperCase().replace( /\./g , '-'));
                location.reload();
            }
        </script>
        <style>
            section.user-id {
                float: left;
                overflow: hidden;
                padding-left: 0;
                padding-right: 1em;
                text-align: right;
                width: 5em;
            }

            section.message {
                border-left: 1px solid #CCCCCC;
                margin-left: 4em;
                overflow: hidden;
                padding-left: 1em;
            }
        </style>
        <!-- for HTML5 el styling -->
        <script>
            document.createElement('article');
            document.createElement('footer');
        </script>

        <script src="https://cdn.webrtc-experiment.com/DataChannel.js"> </script>
        <script src="https://cdn.webrtc-experiment.com/socket.io.js"> </script>
    </head>

    <body>
        <article>
            <header style="text-align: center;">
                <h1>Auto Session Establishment using <a href="https://github.com/muaz-khan/DataChannel" target="_blank">DataChannel.js</a></h1>
                <p>
                    <a href="https://www.webrtc-experiment.com/">HOME</a>
                    <span> &copy; </span>
                    <a href="http://www.MuazKhan.com/" target="_blank">Muaz Khan</a>
                    
                    .
                    <a href="http://twitter.com/WebRTCWeb" target="_blank" title="Twitter profile for WebRTC Experiments">@WebRTCWeb</a>
                    
                    .
                    <a href="https://github.com/muaz-khan?tab=repositories" target="_blank" title="Github Profile">Github</a>
                    
                    .
                    <a href="https://github.com/muaz-khan/DataChannel/issues?state=open" target="_blank">Latest issues</a>
                    
                    .
                    <a href="https://github.com/muaz-khan/DataChannel/commits/master" target="_blank">What's New?</a>
                </p>
            </header>
            
            <div class="github-stargazers"></div>

            <blockquote style="background: #f3b7b7;border: 5px solid black;border-radius: 5px;">
                This demo does NOT works anymore. Please check this one instead: <br>
                <a href="https://www.webrtc-experiment.com/DataChannel/">https://www.webrtc-experiment.com/DataChannel/</a>
            </blockquote>
            
            <table style="border-left: 1px solid black; width: 100%;">
                <tr>
                    <td>
                        <h2 style="display: block; font-size: 1em; text-align: center;">Text Chat</h2>

                        <div id="chat-output"></div>

                        <input type="text" id="user-id" style="font-size: 1.2em; margin-right: 0; width: 5em;" placeholder="all"
                               disabled title="Enter user-id to send direct messages.">
                        <input type="text" id="chat-input" style="font-size: 1.2em; margin-left: -.5em; width: 18em;"
                               placeholder="chat message" disabled>
                    </td>
                    <td style="background: white; border-left: 1px solid black;">
                        <h2 style="display: block; font-size: 1em; text-align: center;">Share Files</h2>
                        <input type="file" id="file" disabled>

                        <div id="file-progress"></div>
                    </td>
                </tr>
            </table>

            <script>
                var channel = new DataChannel(location.hash.substr(1) || 'auto-session-establishment');

                // https://github.com/muaz-khan/WebRTC-Experiment/tree/master/socketio-over-nodejs
                var SIGNALING_SERVER = 'https://socketio-over-nodejs2.herokuapp.com:443/';
                channel.openSignalingChannel = function(config) {
                   var channel = config.channel || this.channel || 'default-namespace';
                   var sender = Math.round(Math.random() * 9999999999) + 9999999999;
                   
                   io.connect(SIGNALING_SERVER).emit('new-channel', {
                      channel: channel,
                      sender : sender
                   });
                   
                   var socket = io.connect(SIGNALING_SERVER + channel);
                   socket.channel = channel;
                   
                   socket.on('connect', function () {
                      if (config.callback) config.callback(socket);
                   });
                   
                   socket.send = function (message) {
                        socket.emit('message', {
                            sender: sender,
                            data  : message
                        });
                    };
                   
                   socket.on('message', config.onmessage);
                };

                channel.onmessage = function(data, userid, latency) {
                    console.debug(userid, 'posted', data);
                    appendDIV(data, userid);
                    console.log('latency:', latency, 'ms');
                };

                channel.onopen = function() {
                    if (document.getElementById('chat-input')) document.getElementById('chat-input').disabled = false;
                    if (document.getElementById('file')) document.getElementById('file').disabled = false;
                    if (useridBox) useridBox.disabled = false;
                };

                channel.onFileProgress = function(packets, uuid) {
                    appendDIV(uuid + ': ' + (
                            packets.sent
                                ? (packets.sent + ' sent')
                                : (packets.received + ' received')
                        ) + ' / ' + packets.remaining + ' remaining', 'file', fileProgress);
                };

                channel.onFileSent = function(file) {
                    appendDIV(file.name + ' sent.', 'file', fileProgress);
                };

                channel.onFileReceived = function(fileName) {
                    appendDIV(fileName + ' received.', 'file', fileProgress);
                };

                document.getElementById('file').onchange = function() {
                    var file = this.files[0];
                    channel.send(file);
                };

                var chatOutput = document.getElementById('chat-output'),
                    fileProgress = document.getElementById('file-progress');

                function appendDIV(data, userid, parent) {
                    var div = document.createElement('div');
                    if (parent) div.innerHTML = data;
                    else {
                        div.innerHTML = '<section class="user-id" contenteditable title="Use his user-id to send him direct messages or throw out of the room!">' + userid + '</section>'
                            + '<section class="message" contenteditable>' + data + '</section>';
                    }

                    if (!parent) chatOutput.appendChild(div, chatOutput.firstChild);
                    else fileProgress.appendChild(div, fileProgress.firstChild);

                    div.tabIndex = 0;
                    div.focus();

                    chatInput.focus();
                }

                var chatInput = document.getElementById('chat-input');
                var useridBox = document.getElementById('user-id');
                chatInput.onkeypress = function(e) {
                    if (e.keyCode !== 13 || !this.value) return;

                    if (useridBox.value.length) {
                        var user = channel.channels[useridBox.value];
                        if (user) user.send(this.value);
                        else return alert('No such user exists.');
                    } else channel.send(this.value);

                    appendDIV(this.value, 'Me');

                    this.value = '';
                    this.focus();
                };

    /* users presence detection */
                channel.onleave = function(userid) {
                    var message = 'A user whose id is ' + userid + ' left you!';
                    appendDIV(message, userid);
                    console.warn(message);
                };

            // channel.leave( userid ); --- eject a user
            // channel.leave(); --- leave the room yourself!
</script>
            <br/>
            <br/>

            <h2>Getting started with WebRTC <a href="https://github.com/muaz-khan/DataChannel"
                                               target="_blank">DataChannel</a></h2>
            <pre>
&lt;script src="https://cdn.webrtc-experiment.com/DataChannel.js"&gt;&lt;/script&gt;
&lt;script&gt;
    var channel = new <strong>DataChannel</strong>('default-channel');

    // to send text/data or file
    channel.<strong>send</strong>(file || data || 'text');
&lt;/script&gt;
</pre>

            <br/><br/>

            <h2>Features:</h2>
            <ol>
                <li>Send file directly &#8212; of any size</li>
                <li>Send text-message of any length</li>
                <li>Send data directly</li>
                <li>Simplest syntax ever! Same like WebSockets.</li>
                <li>Supports fallback to socket.io/websockets/etc.</li>
                <li>Auto users' presence detection</li>
                <li>Allows you eject any user; or close your entire data session</li>
            </ol>
            <br/>
            <br/>

            <h2>Send direct messages!</h2>

            <p>In many-to-many data session; you can share direct messages or files between specific users:</p>
            <pre>
channel.channels[userid].send(file || data || 'text message');
</pre>
            <h2>Detect users' presence</h2>

            <p>To be alerted if a user leaves your room:</p>
            <pre>
channel.onleave = function(userid) {
    // remove that user's photo/image using his user-id
};
</pre>
            <br/>
            <br/>

            <h2>Manually eject a user or close your data session</h2>
            <pre>
channel.leave(userid);  // throw a user out of your room!
channel.leave();        // close your own entire data session
</pre>

            <p>Following things will happen if you are a room owner and you tried to close your data session using <code>channel.leave()</code>:
            </p>

            <ol>
                <li>The entire data session (i.e. all peers, sockets and data ports) will be closed.
                    <small>(from each and every user's side)</small>
                </li>
                <li>All participants will be alerted about room owner's (i.e. yours) action. They'll unable to send any single
                    message over same room because everything is closed!
                </li>
            </ol>

            <h2>Note</h2>: DataChannel.js will never "auto" reinitiate the data session.
            <br/>
            <br/>

            <h2>Additional:</h2>
            <pre>
&lt;script&gt;
    // to be alerted when data ports get open
    channel.<strong>onopen</strong> = function(userid) {
        // user.photo.id = userid; ---- see "onleave" and "leave" above ↑
        
        // direct messages!
        channel.channels[userid].send(file || data || 'text message');
    }
	
    // to be alerted when data ports get new message
    channel.<strong>onmessage</strong> = function(message, userid) {
        // send direct message to same user using his user-id
        channel.channels[userid].send('cool!');
    }
	
    // show progress bar!
    channel.<strong>onFileProgress</strong> = function (packets) {
        // packets.remaining
        // packets.sent
        // packets.received
        // packets.length
    };

    // on file successfully sent
    channel.<strong>onFileSent</strong> = function (file) {
        // file.name
        // file.size
    };

    // on file successfully received
    channel.<strong>onFileReceived</strong> = function (fileName) {};
&lt;/script&gt;
</pre>
            <br/>
            <br/>

            <h2>Errors Handling</h2>
            <pre>
&lt;script&gt;
    // error to open data ports
    channel.<strong>onerror</strong> = function(event) {}
	
    // data ports suddenly dropped
    channel.<strong>onclose</strong> = function(event) {}
&lt;/script&gt;
</pre>
            <br/>
            <br/>

            <h2>Use your own socket.io for signaling</h2>
            <pre>
&lt;script&gt;
    // by default socket.io is used for signaling; you can override it
    var channel = new <strong>DataChannel</strong>('default-channel', {
        openSignalingChannel: function(config) {
            var socket = io.connect('http://your-site:8888');
            socket.channel = config.channel || this.channel || 'default-channel';
            socket.on('message', config.onmessage);

            socket.send = function (data) {
                socket.emit('message', data);
            };

            if (config.onopen) setTimeout(config.onopen, 1);
            return socket;
        }
    });
&lt;/script&gt;
</pre>
            <br/>
            <br/>
            <section style="border: 1px solid rgb(189, 189, 189); border-radius: .2em; margin: 1em 3em;">
                <h2 id="feedback" style="border-bottom: 1px solid rgb(189, 189, 189); padding: .2em .4em;">Feedback</h2>

                <div>
                    <textarea id="message"
                              style="border: 1px solid rgb(189, 189, 189); height: 8em; margin: .2em; outline: none; resize: vertical; width: 98%;"
                              placeholder="Have any message? Suggestions or something went wrong?"></textarea>
                </div>
                <button id="send-message" style="font-size: 1em;">Send Message</button>
            </section>
            
            <section class="experiment own-widgets latest-commits">
                <h2 class="header" id="updates" style="color: red; padding-bottom: .1em;"><a href="https://github.com/muaz-khan/WebRTC-Experiment/commits/master" target="_blank">Latest Updates</a></h2>
                <div id="github-commits"></div>
            </section>
        </article>
        
        <a href="https://github.com/muaz-khan/DataChannel" class="fork-left"></a>
        
        <footer>
            <p>
                <a href="https://www.webrtc-experiment.com/">WebRTC Experiments</a>
                © <a href="https://plus.google.com/+MuazKhan" rel="author" target="_blank">Muaz Khan</a>
                <a href="mailto:muazkh@gmail.com" target="_blank">muazkh@gmail.com</a>
            </p>
        </footer>
        <script src="https://cdn.webrtc-experiment.com/commits.js"> </script>
    </body>
</html>
